@file:OptIn(ExperimentalUuidApi::class)

package com.harth.blemultiplatform.ble

import com.harth.blemultiplatform.ble.core.CharacteristicProperty
import com.harth.blemultiplatform.ble.core.WriteType
import kotlinx.coroutines.flow.Flow
import no.nordicsemi.kotlin.ble.client.RemoteCharacteristic
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.Uuid

class NativeCharacteristic(
    override val service: IService,
    val characteristic: RemoteCharacteristic,
) : ICharacteristic {

    override val uuid: Uuid = characteristic.uuid

    override val descriptors: List<IDescriptor> =
        characteristic.descriptors.map { NativeDescriptor(it, this) }

    override val properties: List<CharacteristicProperty> = characteristic.properties.map {
        when (it) {
            no.nordicsemi.kotlin.ble.core.CharacteristicProperty.BROADCAST -> CharacteristicProperty.BROADCAST
            no.nordicsemi.kotlin.ble.core.CharacteristicProperty.READ -> CharacteristicProperty.READ
            no.nordicsemi.kotlin.ble.core.CharacteristicProperty.WRITE_WITHOUT_RESPONSE -> CharacteristicProperty.WRITE_WITHOUT_RESPONSE
            no.nordicsemi.kotlin.ble.core.CharacteristicProperty.WRITE -> CharacteristicProperty.WRITE
            no.nordicsemi.kotlin.ble.core.CharacteristicProperty.NOTIFY -> CharacteristicProperty.NOTIFY
            no.nordicsemi.kotlin.ble.core.CharacteristicProperty.INDICATE -> CharacteristicProperty.INDICATE
            no.nordicsemi.kotlin.ble.core.CharacteristicProperty.SIGNED_WRITE -> CharacteristicProperty.SIGNED_WRITE
            no.nordicsemi.kotlin.ble.core.CharacteristicProperty.EXTENDED_PROPERTIES -> CharacteristicProperty.EXTENDED_PROPERTIES
        }
    }

    override val isNotifying: Boolean
        get() = characteristic.isNotifying

    override suspend fun setNotifying(enabled: Boolean) {
        return characteristic.setNotifying(enabled)
    }

    override suspend fun read(): ByteArray {
        return characteristic.read()
    }

    override suspend fun write(
        data: ByteArray,
        writeType: WriteType
    ) {
        characteristic.write(data, writeType.toWriteType())
    }

    override suspend fun subscribe(): Flow<ByteArray> {
        TODO("Not yet implemented")
    }

    override suspend fun waitForValueChange(): ByteArray {
        TODO("Not yet implemented")
    }
}